/*
 * Copyright (c) 2024 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
 */

#ifndef LOG_RPC_H_
#define LOG_RPC_H_

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

/**
 * @file
 * @defgroup log_rpc nRF RPC logging
 * @{
 * @brief Logging over nRF RPC
 */

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief nRF RPC logging level.
 */
enum log_rpc_level {
	LOG_RPC_LEVEL_NONE = 0,
	LOG_RPC_LEVEL_ERR,
	LOG_RPC_LEVEL_WRN,
	LOG_RPC_LEVEL_INF,
	LOG_RPC_LEVEL_DBG,
};

/**
 * @brief Log history handler.
 *
 * The type of a callback function that is invoked for each received log message
 * while fetching the log history from the remote device.
 *
 * @param level		The message level, see @ref log_rpc_level.
 * @param msg		A pointer to the message payload.
 * @param msg_len	The message payload length.
 */
typedef void (*log_rpc_history_handler_t)(enum log_rpc_level level, const char *msg,
					  size_t msg_len);

/** @brief Log history threshold reached handler.
 *
 * The type of a callback function that is invoked when the log history usage
 * threshold configured with @ref log_rpc_set_history_level has been reached for
 * the first time.
 */
typedef void (*log_rpc_history_threshold_reached_handler_t)(void);

/**
 * @brief Sets the log streaming verbosity level.
 *
 * The log streaming is the feature of nRF RPC logging that allows receiving log
 * messages as they are generated by the application running on the remote device.
 *
 * This function issues an nRF RPC command that configures the remote device to
 * stream log messages whose level is less than or equal to the specified level.
 *
 * @param level	Logging level, see @ref log_rpc_level.
 */
void log_rpc_set_stream_level(enum log_rpc_level level);

/**
 * @brief Sets the log history verbosity level.
 *
 * The log history is the feature of nRF RPC logging that allows saving log
 * messages generated by the application running on the remote device into
 * a ring buffer, and then retrieving the log history when needed.
 *
 * This function issues an nRF RPC command that configures the remote device to
 * save log messages whose level is less than or equal to the specified level.
 *
 * @param level	Logging level, see @ref log_rpc_level.
 */
void log_rpc_set_history_level(enum log_rpc_level level);

/**
 * @brief Gets the current history usage threshold.
 *
 * This function fetches the current history usage threshold.
 *
 * @returns The current history usage threshold in percentage.
 */
uint8_t log_rpc_get_history_usage_threshold(void);

/**
 * @brief Gets the current history usage size in bytes.
 *
 * This function fetches the current history usage size in bytes.
 *
 * @returns The current history usage size in bytes.
 */
size_t log_rpc_get_history_usage_current(void);

/**
 * @brief Gets the maximum history size in bytes.
 *
 * This function fetches the maximum history size in bytes.
 *
 * @returns The maximum history size in bytes.
 */
size_t log_rpc_get_history_usage_max(void);

/**
 * @brief Sets the current history usage threshold.
 *
 * The log history is the feature of nRF RPC logging that allows saving log
 * messages generated by the application running on the remote device into
 * a ring buffer, and then retrieving the log history when needed.
 *
 * This function issues an nRF RPC command that requests the remote device to
 * emit an nRF RPC event when the ring buffer occupancy exceeds the requested
 * threshold for the first time after the threshold is set or the log history
 * is flushed.
 *
 * @param handler	The handler that is invoked when the configured log
 *			history usage threshold has been reached, see
 *			@ref log_rpc_history_threshold_reached_handler_t.
 * @param threshold	The history usage threshold in percentage (0 - 100).
 *			Passing 0 disables this feature.
 */
void log_rpc_set_history_usage_threshold(log_rpc_history_threshold_reached_handler_t handler,
					 uint8_t threshold);

/**
 * @brief Fetches the log history.
 *
 * This function issues an nRF RPC command that starts the log history transfer
 * from the remote device. The @c handler callback function is invoked for each
 * received log message. Additionally, it is invoked with @c msg argument set to
 * NULL after all log messages have been received.
 *
 * @note If the function is called while the previous log history transfer is
 *       still is in progress, the process is restarted from the current oldest
 *       log message saved in the log history on the remote device.
 *
 * @param handler	History handler, see @ref log_rpc_history_handler_t.
 *
 * @retval 0		On success.
 * @retval -errno	On failure.
 */
int log_rpc_fetch_history(log_rpc_history_handler_t handler);

/**
 * @brief Stops the log history transfer.
 *
 * This function issues an nRF RPC command that stops the log history transfer.
 *
 * @param pause		Indicates that the transfer should be put on hold rather
 *			than cancelled, which means that the history overwriting
 *			is kept disabled and the transfer position is retained
 *			so that the transfer can be resumed later on.
 */
void log_rpc_stop_fetch_history(bool pause);

/**
 * @brief Retrieves the crash dump saved on the remote device.
 *
 * This function issues an nRF RPC command to obtain a subsequent chunk of the
 * last crash dump saved on the remote device, and then it puts the received
 * chunk into the provided buffer.
 *
 * The remote may either send the entire dump in one go, if it fits within
 * the output buffer, or it may send a chunk of the log. Therefore, the caller
 * should repeatedly call this function, with an increasing offset, until it
 * returns 0 (indicating no more data), or a negative value (indicated an error).
 *
 * @param offset        Crash log offset.
 * @param buffer        Output buffer to copy the received log chunk.
 * @param buffer_length Output buffer length.
 *
 * @returns             The number of characters copied into the output buffer.
 * @returns -errno      Indicates failure.
 */
int log_rpc_get_crash_dump(size_t offset, uint8_t *buffer, size_t buffer_length);

/**
 * @brief Invalidates the crash dump saved on the remote device.
 *
 * This function issues an nRF RPC command to mark the crash dump saved on
 * the remote device as invalid, so that it can no longer be retrieved by
 * @ref log_rpc_get_crash_dump function.
 *
 * @returns 0           Indicates success.
 * @returns -errno      Indicates failure.
 */
int log_rpc_invalidate_crash_dump(void);

/**
 * @brief Generates a log message on the remote device.
 *
 * This function issues an nRF RPC command that requests the remote device to
 * generate a log message with the given level. This function can be used to
 * test other functions of Logging over nRF RPC library.
 *
 * @param level		Logging level, see @ref log_rpc_level.
 * @param message	Log message C string.
 */
void log_rpc_echo(enum log_rpc_level level, const char *message);

/**
 * @brief Sets the current time used for log timestamping.
 *
 * This function issues an nRF RPC command that configures the remote device
 * with the current time that should be used for timestamping new log messages.
 *
 * @note The remote device may enable log buffering and log messages are time-
 *	 stamped before they are enqueued in the log buffer, so this function
 *	 may not have an immediate effect and you may still observe a few
 *	 messages timestamped with the old time after this function exits.
 *
 * @param now_us	The current time in microseconds.
 */
void log_rpc_set_time(uint64_t now_us);

#ifdef __cplusplus
}
#endif

/**
 *@}
 */

#endif /* LOG_RPC_H_ */
